package com.zhaoyue.study.io.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created with IntelliJ IDEA.
 * User: Administrator
 * Date: 2016/12/16
 * Time: 11:16
 * To change this template use File | Settings | File Templates.
 */
public class Server {

    private Selector selector = getSelector();

    public Selector getSelector() {
        try {
            return Selector.open();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private ServerSocketChannel serverSocketChannel = null;
    private ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 20, 500, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(20));

    private Map<Integer,SelectionKey> selectionKeyMap = new ConcurrentHashMap<>();
    private Map<Integer,List<Object>> resposneMessageQueue = new ConcurrentHashMap<>();

    private volatile boolean run = true;
    private volatile boolean isClose = false;

    public Server(){
        try{
            serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.bind(new InetSocketAddress(5555));//绑定端口
            serverSocketChannel.configureBlocking(false);//设置非阻塞模式
            if(selector == null){
                selector = Selector.open();
            }
            serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);//channel 注册到选择器中
        }catch (Exception e){
            e.printStackTrace();
            close();
        }
    }

    /**
     * 关闭
     */
    private void close(){
        run = false;
        isClose = true;
        threadPoolExecutor.shutdown();//阻止添加新的任务，等待线程池中的执行完成
        try{
            if(serverSocketChannel != null){
                serverSocketChannel.close();
            }
            if(selector != null){
                selector.close();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 启动选择器监听客户端时间
     */
    private void start(){
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try{
                    while (run){
                        if(selector.select(10) == 0){
                            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                            while (iterator.hasNext()){
                                SelectionKey selectionKey = iterator.next();
                                iterator.remove();
                                if(selectionKey.isReadable()){
                                    if(selectionKeyMap.get(selectionKey.hashCode()) != selectionKey){

                                    }
                                }else if(selectionKey.isWritable()){

                                }else if(selectionKey.isAcceptable()){

                                }
                            }
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        };

        threadPoolExecutor.execute(runnable);
    }

}
